package team.hyznrj.studentsys.security;

import java.util.List;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import team.hyznrj.studentsys.dao.repository.account.AccountInfoRepository;
import team.hyznrj.studentsys.entity.account.AccountInfo;
import team.hyznrj.studentsys.service.LoginPowerRegisterService;

@Component
public class LoginRealm extends AuthorizingRealm {
	@Autowired
	@Lazy
	AccountInfoRepository accountInfoRepository;
	@Autowired
	@Lazy
	LoginPowerRegisterService loginService;
	{
		this.setAuthenticationCachingEnabled(true);
		//这里sampleCache1可自定义，在ehcache里设置
		this.setAuthenticationCacheName("sampleCache1");
	}
	/**
	 * 缓存清除实例，如果开了缓存的话 login(u1.getUsername(), password);
	 * userService.changePassword(u1.getId(), password + "1");
	 * RealmSecurityManager securityManager = (RealmSecurityManager)
	 * SecurityUtils.getSecurityManager(); UserRealm userRealm = (UserRealm)
	 * securityManager.getRealms().iterator().next();
	 * userRealm.clearCachedAuthenticationInfo(subject().getPrincipals());
	 * login(u1.getUsername(), password + "1");
	 */
	/*
	 * 权限认证,发生在有 注解的接口/有映射关系的地方上 如果是注解，会抛出异常，可统一处理 如果是映射关系，不会抛异常，会跳转到无权限页面
	 * 这个方法只在需要的时候被调用，可设置缓存，但 记得修改密码等，要清除缓存
	 * 缓存效果:有缓存则不执行doGetAuthorizationInfo获取权限
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		/** 获取username */
		String username = (String) principalCollection.getPrimaryPrincipal();
		AccountInfo account = accountInfoRepository.findByUserAccount(username);
		/** 授权 */
		List<String> loginPermission = loginService.getPowerUrls(account.getRoleId());
		if (loginPermission != null && loginPermission.size() > 0) {
			info.addStringPermissions(loginPermission);
		}
		return info;
	}

	/**
	 * 从数据库中获取用户名、密码
	 * ShiRo权限认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String username = token.getUsername();
		if(!StringUtils.isEmpty(username)){
			AccountInfo user = accountInfoRepository.findByUserAccount(username);
			if(user!=null){
				return new SimpleAuthenticationInfo(user.getUserAccount(), user.getUserPassword(), getName());
			}
		}
		return null;
	}

}
